package com.fulu.game.bi.service.impl.auth;

import cn.hutool.core.collection.CollectionUtil;
import com.fulu.game.bi.common.exception.BizException;
import com.fulu.game.bi.common.util.lang.StringUtils;
import com.fulu.game.bi.entity.enums.GroupRelTableEnum;
import com.fulu.game.bi.entity.enums.StatusEnum;
import com.fulu.game.bi.entity.po.auth.BiPermission;
import com.fulu.game.bi.entity.po.auth.BiRole;
import com.fulu.game.bi.entity.po.auth.BiUser;
import com.fulu.game.bi.entity.po.channel.GroupRel;
import com.fulu.game.bi.entity.vo.auth.permission.RoleVO;
import com.fulu.game.bi.entity.vo.auth.role.RoleQueryVO;
import com.fulu.game.bi.entity.vo.auth.role.RoleSaveVO;
import com.fulu.game.bi.enums.CommonlyOrderEnums;
import com.fulu.game.bi.mysql.bi.auth.BiPermissionDao;
import com.fulu.game.bi.mysql.bi.auth.BiRoleDao;
import com.fulu.game.bi.mysql.bi.channel.GroupRelDao;
import com.fulu.game.bi.redis.service.auth.BiPermissionService;
import com.fulu.game.bi.redis.service.auth.BiRoleService;
import com.fulu.game.bi.redis.service.auth.BiUserService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class RoleServiceImpl implements BiRoleService {

    @Autowired
    private BiRoleDao biRoleDao;

    @Autowired
    private BiUserService biUserService;

    @Autowired
    private GroupRelDao groupRelDao;

    @Autowired
    private BiPermissionService permissionService;

    @Override
    public PageInfo<BiRole> list(RoleQueryVO vo) {
        PageHelper.startPage(vo.getPageNum(), vo.getPageSize(), CommonlyOrderEnums.UPDATE_DESC.getValue());

        List<BiRole> list = biRoleDao.list(vo);

        return new PageInfo(list);
    }

    @Override
    public BiRole save(RoleSaveVO vo) {
        if (Objects.isNull(vo.getId())) {
            return createNewRole(vo);
        }

        return updateExistRole(vo);
    }

    public void unBindPermission(Integer roleId, List<Integer> permissionIdList) {
        List<GroupRel> records = permissionIdList.stream()
                .map(permissionId -> {
                    GroupRel groupRel = new GroupRel();
                    groupRel.setGroupId(roleId);
                    groupRel.setRelId(permissionId);
                    return groupRel;
                })
                .collect(Collectors.toList());

        records.forEach(rel -> groupRelDao.delete(rel, GroupRelTableEnum.ROLE_PERMISSION.getName()));
    }


    @Override
    public void bindPermission(Integer roleId, List<Integer> permissionIdList) {
        List<GroupRel> records = permissionIdList.stream()
                .map(permissionId -> {
                    GroupRel groupRel = new GroupRel();
                    groupRel.setGroupId(roleId);
                    groupRel.setRelId(permissionId);
                    return groupRel;
                })
                .collect(Collectors.toList());

        groupRelDao.insert(records, GroupRelTableEnum.ROLE_PERMISSION.getName());
    }

    private BiRole updateExistRole(RoleSaveVO vo) {

        if (StringUtils.isNotEmpty(vo.getName())) {
            checkNameUniq(vo);
        }

        Date now = new Date();
        BiUser currentUser = biUserService.getCurrentUser();

        BiRole biRole = new BiRole();
        BeanUtils.copyProperties(vo, biRole);
        biRole.setOperatorId(currentUser.getId());
        biRole.setOperatorName(currentUser.getName());
        biRole.setUpdateTime(now);

        biRoleDao.updateSelective(biRole);

        bindRolePemissionRel(vo);

        return biRole;
    }

    private void checkNameUniq(RoleSaveVO vo) {
        BiRole nameRole = biRoleDao.findByName(vo.getName());

        if (Objects.nonNull(nameRole) && !Objects.equals(nameRole.getId(), vo.getId())) {
            throw new BizException("角色名称已存在");
        }
    }

    private BiRole createNewRole(RoleSaveVO vo) {
        Date now = new Date();
        BiUser currentUser = biUserService.getCurrentUser();

        BiRole nameRole = biRoleDao.findByName(vo.getName());

        if (Objects.nonNull(nameRole)) {
            throw new BizException("角色名称已存在");
        }

        BiRole biRole = new BiRole();
        BeanUtils.copyProperties(vo, biRole);
        biRole.setStatus(StatusEnum.YES.getStatus());
        biRole.setIsDel(StatusEnum.NO.getStatus());
        biRole.setOperatorId(currentUser.getId());
        biRole.setOperatorName(currentUser.getName());
        biRole.setCreateTime(now);
        biRole.setUpdateTime(now);

        biRoleDao.insert(biRole);

        vo.setId(biRole.getId());
        bindRolePemissionRel(vo);

        log.info("添加角色成功： {}", biRole);

        return biRole;
    }

    private void bindRolePemissionRel(RoleSaveVO vo) {
        if (CollectionUtil.isNotEmpty(vo.getRouterIds())) {
              groupRelDao.deleteByGroupId(vo.getId(), GroupRelTableEnum.ROLE_PERMISSION.getName());

            List<GroupRel> list = vo.getRouterIds().stream()
                    .map(routeId -> {
                        GroupRel g = new GroupRel();
                        g.setGroupId(vo.getId());
                        g.setRelId(routeId);
                        return g;
                    })
                    .collect(Collectors.toList());
            groupRelDao.insert(list, GroupRelTableEnum.ROLE_PERMISSION.getName());
        }
    }

    @Override
    public BiRole findById(Integer id) {
        BiRole biRole = biRoleDao.findById(id);

        RoleVO relevo = permissionService.findAllByRoleId(id);

        biRole.setRouterList(relevo.getRouterList());

        return biRole;
    }

    @Override
    public void deleteById(Integer id) {
        biRoleDao.deleteById(id);
        groupRelDao.deleteByGroupId(id, GroupRelTableEnum.ROLE_PERMISSION.getName());
    }
}
